filter([],_,[]).
filter([X|LST],OK,[XP|LSTP]) :- intersection(X,OK,XP), XP\=[], filter(LST,OK,LSTP), !.
filter([_|LST],OK,LSTP) :- filter(LST,OK,LSTP).
  

alldots([]).
alldots([ctx(_,dot)|LST]) :- alldots(LST).

partby([],_,[]).
partby([X|LST],PA,RET) :-
  X=ctxm(D,P,_,_,_),
  not((member(LP,PA),member(ctx(D,P),LP))), !, partby(LST,PA,RET).
partby([X|LST],PA,[XP|DP]) :-
  X=ctxm(D,P,_,_,_),
  member(LP,PA),
  member(ctx(D,P),LP),
  findall(Z,(member(Z,LST),Z=ctxm(DZ,PZ,_,_,_),member(ctx(DZ,PZ),LP)),LSTZ),
  findall(V,member(ctxm(_,_,_,V,_),[X|LSTZ]),LSTV),
  list_to_set(LSTV,XP),
  subtract(LST,LSTZ,LSTR),
  partby(LSTR,PA,DP).

partby2([],_,[]).
partby2([X|LST],PA,RET) :-
  X=ctxm(D,P,_,_,_),
  not((member(LP,PA),member(ctx(D,P),LP))), !, partby(LST,PA,RET).
partby2([X|LST],PA,[[X|XP]|DP]) :-
  X=ctxm(D,P,_,_,_),
  member(LP,PA),
  member(ctx(D,P),LP),
  findall(Z,(member(Z,LST),Z=ctxm(DZ,PZ,_,_,_),member(ctx(DZ,PZ),LP)),LSTZ),
  list_to_set(LSTZ,XP),
  subtract(LST,LSTZ,LSTR),
  partby2(LSTR,PA,DP).

% nosubsets(L1,L1,R): returns all elements in L1 that are not proper subsets of other elements in L1
nosubsets(_,[],[]).
nosubsets(L1,[X|L],R) :- member(Z,L1), X\=Z, subset(X,Z), nosubsets(L1,L,R), !.
nosubsets(L1,[X|L],[X|R]) :- nosubsets(L1,L,R).

coaknow(A,LR) :- dis(A,L),contexts(L,C),linkablepart(A,C,CP),partby(L,CP,LP),nosubsets(LP,LP,LR).

take(_,0,[]).
take(A,1,[(A,s)]).
take(A,2,[A]).

coalition(L) :-
  member(RU1,[0,1,2]), take(umc1,RU1,L1),
  member(RU2,[0,1,2]), take(umc2,RU2,L2),
  member(RU3,[0,1,2]), take(umc3,RU3,L3),
  member(RCI,[0,1,2]), take(ci,RCI,L4),
  member(RPS,[0,1,2]), take(ps,RPS,L5),
  member(RR,[0,1,2]), take(r,RR,L6),
  append([L1,L2,L3,L4,L5,L6],L),
  L\=[].

coa :-
 findall(L,(coalition(L), coaknow(L,LR),print(L),print('|'),print(LR),print('\n')),_).


toiois1([],[]).
toiois1([X1|LST1],[X2|LST2]) :- ioi(X1,X2), !, toiois1(LST1,LST2).
toiois1([_|LST1],LST2) :- toiois1(LST1,LST2).

toiois([],[]).
toiois([X1|LST1],[X2|LST2]) :- toiois1(X1,X2), X2\=[], !, toiois(LST1,LST2).
toiois([_|LST1],LST2) :- toiois(LST1,LST2).

noiois1([],[]).
noiois1([X|LST1],[X|LST2]) :- not(ioi(X,_)), !, noiois1(LST1,LST2).
noiois1([_|LST1],LST2) :- noiois1(LST1,LST2).

noioisx([],[]).
noioisx([X1|LST1],[X2|LST2]) :- noiois1(X1,X2), noioisx(LST1,LST2).

noiois(LST1,RET) :- noioisx(LST1,LST2), append(LST2,LST3), list_to_set(LST3,RET).

custompropx(A,X) :- current_predicate(customprop/2), customprop(A,X).


% ----- coalitions to consider for coa graph ----------------------------------

drawcoalitionx(_) :- not(current_predicate(drawcoalition/1)), !.
drawcoalitionx(SET) :- drawcoalition(SET).

coalt1(X,C2) :- member(X,C2).
coalt1(X,C2) :- X=(A,s), member(A,C2).

coalt(C1,C2) :- forall(member(X,C1),coalt1(X,C2)).

coalitions(SET) :-
  findall(A,knows(A,_),LSTA),      % all actors
  list_to_set(LSTA,SETA),
  findall(COA,(nesub(COA,SETA),
               drawcoalitionx(COA),
               not((member(A,COA),member((A,s),COA)))
              ),SET).

%  findall(COA,(member(COA,SCOA),not(
%                     member(COAP,SCOA),coalt(COAP,COA),not((member(A1,COA),knows(A1,M),not((member(B1,COAP),knows(B1,M)))))
%  ))).
%  SET=SCOA.
